package top.honlnk.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import top.honlnk.common.constant.UserConstant;
import top.honlnk.common.exception.CustomException;
import top.honlnk.common.exception.OCRPartialWarnException;
import top.honlnk.common.network.GetOCRAccessTokenNetwork;
import top.honlnk.common.utils.BaiduOCRTableResultValidatorUtil;
import top.honlnk.mapper.PublicMapper;
import top.honlnk.mapper.ServiceStaffMapper;
import top.honlnk.mapper.UserMapper;
import top.honlnk.common.network.GetImageOCRDataNetwork;
import top.honlnk.pojo.dto.UploadTableDTO;
import top.honlnk.pojo.dto.UserUpdateTableDTO;
import top.honlnk.pojo.entity.OcrAdminInfo;
import top.honlnk.pojo.entity.RotaSecretKey;
import top.honlnk.pojo.entity.SchoolTimetable;
import top.honlnk.pojo.vo.CondensedDataVO;
import top.honlnk.pojo.vo.SubmitIdValidationResultVO;
import top.honlnk.service.impl.processor.AutoSetAccessTokenProcessor;
import top.honlnk.service.impl.processor.GenerateSubmissionIdProcessor;
import top.honlnk.service.impl.processor.ImageDataParserProcessor;
import top.honlnk.common.utils.ImageFileToBase64Util;
import top.honlnk.common.utils.StringToArrayUtil;
import top.honlnk.service.UserService;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private PublicMapper publicMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ServiceStaffMapper serviceStaffMapper;

    @Autowired
    private AutoSetAccessTokenProcessor autoSetAccessTokenProcessor;

    @Override
    public CondensedDataVO upload(MultipartFile file, String key, String name) {

        // 图片转换为 base64 编码，因为百度的OCR图片识别接收的图片数据是base64编码的
        ImageFileToBase64Util imageFileToBase64Util = new ImageFileToBase64Util();
        String base64EncodedFile = imageFileToBase64Util.ProcessorData(file);

        // 获取百度OCR的访问令牌以及配置信息
        OcrAdminInfo ocrAdminInfo = userMapper.getOcrAdminInfo(UserConstant.OCR_IMAGE_TABLE);
        // 调用网络接口获取图片表格对应的json数据
        GetImageOCRDataNetwork getImageOCRDataNetwork = new GetImageOCRDataNetwork();
        // 通过发送http请求的方式，使用百度OCR云服务识别图片表格，并返回一个json数据
        JSONObject imageOCRData = getImageOCRDataNetwork.getImageOCRData(base64EncodedFile, ocrAdminInfo);
        if (imageOCRData.has("custom_error")) {

            GetOCRAccessTokenNetwork getOCRAccessTokenNetwork = new GetOCRAccessTokenNetwork();
            String accessToken = getOCRAccessTokenNetwork.getOCRAccessToken(ocrAdminInfo);
            userMapper.setAccessToken(accessToken, UserConstant.OCR_IMAGE_TABLE);
            ocrAdminInfo.setAccessToken(accessToken);
            log.warn(UserConstant.SYSTEM_AUTO_UPDATE_OCR_TOKEN, LocalDate.now());
            // 获取所有服务人员的邮箱
            List<String> mailList = serviceStaffMapper.getServiceStaffMailList();
            String[] mailArray = mailList.toArray(new String[0]);
            autoSetAccessTokenProcessor.autoSetAccessToken(mailArray, accessToken);

            imageOCRData = getImageOCRDataNetwork.getImageOCRData(base64EncodedFile, ocrAdminInfo);
        }
        log.info(UserConstant.OCR_IMAGE_CONTENT, imageOCRData);

        // 验证百度OCR识别结果
        BaiduOCRTableResultValidatorUtil baiduOCRTableResultValidatorUtil = new BaiduOCRTableResultValidatorUtil();
        imageOCRData = baiduOCRTableResultValidatorUtil.validator(imageOCRData);
        // 解析json数据为一个二维数组
        ImageDataParserProcessor imageDataParserProcessor = new ImageDataParserProcessor();
        String[][] condensedArray = imageDataParserProcessor.ProcessorData(imageOCRData);

        CondensedDataVO condensedDataVO = setTable(condensedArray, name, key);

        try {
            if (imageOCRData.has("table_num")) {

                if (imageOCRData.getInt("table_num") > 1) {
                    throw new OCRPartialWarnException(UserConstant.OCR_IMAGE_PARTIAL_WARN, condensedDataVO);
                }
            }
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }

        return condensedDataVO;
    }

    @Override
    public CondensedDataVO uploadTable(@NotNull UploadTableDTO uploadTableDTO, String key) {
        String[][] condensedArray = uploadTableDTO.getTable();

        String name = uploadTableDTO.getName();
        return setTable(condensedArray, name, key);
    }

    private CondensedDataVO setTable(String[][] condensedArray, String name, String key) {
        // 生成提交信息id
        GenerateSubmissionIdProcessor generateSubmissionIdProcessor = new GenerateSubmissionIdProcessor();
        String encode = generateSubmissionIdProcessor.encode();

        // 根据查询rota_secret_key表，获取对应的id
        RotaSecretKey rotaSecretKey = publicMapper.getRotaSecretKeyLike(key);
        Integer keyId = rotaSecretKey.getId();

        // 将数据保存到实体类中
        SchoolTimetable schoolTimetable = new SchoolTimetable();
        schoolTimetable.setKeyId(keyId);
        schoolTimetable.setName(name);

        // 条件判断 schoolTimetable 表中有没有key_id与name的信息同时存在的字段，如果有说明已经上传过一次表格那么执行修改操作，如果没有说明是第一次上传执行插入操作
        boolean isUnique = userMapper.getUnique(schoolTimetable);
        schoolTimetable.setSubmitId(encode);
        schoolTimetable.setTable(Arrays.deepToString(condensedArray));
        if (isUnique) {
            log.info("修改");
            userMapper.updateByUpload(schoolTimetable);
        }
        if (!isUnique){
            log.info("插入");
            userMapper.insertByUpload(schoolTimetable);
        }

        return CondensedDataVO.builder()
                .submitId(encode)
                .name(name)
                .course(condensedArray)
                .build();
    }

    @Override
    public CondensedDataVO getTable(String id) {
        SchoolTimetable schoolTimetable = userMapper.getSchoolTimetableBySubmitId(id);
        StringToArrayUtil stringToArrayUtil = new StringToArrayUtil();
        String[][] userGetTable = stringToArrayUtil.stringTo2DArray(schoolTimetable.getTable());
        return CondensedDataVO.builder()
                .submitId(schoolTimetable.getSubmitId())
                .name(schoolTimetable.getName())
                .course(userGetTable)
                .build();
    }

    @Override
    public void setTable(@NotNull UserUpdateTableDTO userUpdateTableDTO, String submitId) {
        userMapper.updateTableBySubmitId(submitId, Arrays.deepToString(userUpdateTableDTO.getTable()));
    }


    @Override
    public void validateSubmitId(@NotNull String id) {
        if (id.isEmpty()) {
            throw new CustomException("提交信息id不能为空，请检查提交信息id是否正确！");
        }
        if (!userMapper.validate(id)) {
            throw new CustomException("提交信息不存在，请检查提交信息id是否正确！");
        }
    }

    @Override
    public List<SubmitIdValidationResultVO> validateSubmitIdList(List<String> submitIds) {
        List<SchoolTimetable> schoolTimetables = userMapper.getTableBySubmitId(submitIds);
        List<SubmitIdValidationResultVO> resultList = new ArrayList<>();

        for (String submitId : submitIds ) {
            // 初始化标志变量
            boolean isValid = false;

            for (SchoolTimetable schoolTimetable : schoolTimetables) {
                if (submitId.equals(schoolTimetable.getSubmitId())) {
                    isValid = true;
                    break;
                }
            }
            SubmitIdValidationResultVO vo = new SubmitIdValidationResultVO();
            vo.setSubmitId(submitId);
            vo.setValid(isValid);

            // 将对象添加到结果列表中
            resultList.add(vo);
        }
        return resultList;
    }
}
